STAT4 : RELATION ENTRE DEUX VARIABLES QUALITATIVES

Exo1 : Tableau de contingence et test du chi-2

Auteur·rice

Jean-Paul NGBESSO & Claude GRASLAND

Date de publication

2025-05-27

Le but de ce TD est de mettre en oeuvre le cours sur le tableau de contingence et le test du chi-2 fournissant un programme type d’analyse de la relation entre deux variables X et Y qualitatives à l’aide de R. Ce programme pourra ensuite être facilement adapaté à d’autres jeux de données.

Télécharger l’exercice

1. PREPARATION DES DONNEES

1.1. Chargement des données

On charge un fichier contenant les résultats d’une enquête.

  • Très important : On ajoute l’instruction stringAsFactors=TRUE pour que toutes les variables de type caractère deveiennent des variables de type factor.
don <- read.table(file = "data/civ_afrobarometer_2023/data/survey_data.csv", # nom du fichier et chemin d'accès
                  sep = ";",                     # séparateur (ici, des points-virgule)
                  dec=",",                       # Type de décimale
                  header = TRUE,                 # ligne d'en-tête avec le nom des variables
                  encoding="UTF-8",              # encodage adapté au français
                  stringsAsFactors = TRUE)       # Transforme les character en factor     

1.2 Chargement des métadonnées

On charge ensuite un tableau contenant des informations sur les variables et leurs modalités

meta <- read.table(file = "data/civ_afrobarometer_2023/data/survey_meta.csv", # nom du fichier et chemin d'accès
                  sep = ";",                     # séparateur (ici, des points-virgule)
                  dec=",",                       # Type de décimale
                  header = TRUE,                 # ligne d'en-tête avec le nom des variables
                  encoding="UTF-8")              # encodage adapté au français

## Affichage des métadonnées
meta
          code
1       RESPNO
2  withinwt_ea
3       URBRUR
4       REGION
5     EA_SVC_A
6     EA_SVC_B
7     EA_FAC_B
8    EA_ROAD_C
9      THISINT
10    ADULT_CT
11       CALLS
12          Q1
13          Q2
14        Q46F
15        Q46G
16        Q46H
17        Q46I
18        Q57A
19        Q57B
20        Q58A
21        Q58C
22        Q90D
23        Q90F
24        Q90G
25        Q91C
26        Q92A
27         Q94
28      LENGTH
29        Q101
30        Q102
31        Q103
                                                                     def
1                                                    Numéro du répondant
2                                       Facteur de pondération nationale
3                                        Type de milieu: Urbain ou Rural
4                                                                 Région
5                                 EA-SVC-A. Réseau électrique dans la ZD
6                         EA-SVC-B. Système d'adduction d'eau dans la ZD
7                                             EA-FAC-B. École dans la ZD
8                       EA-ROAD-C. État de la route sur les derniers 5km
9                                                    Cet entretien, sexe
10                             Nombre de citoyens adultes dans le ménage
11                                                     Nombre de visites
12                                                               Q1. Age
13                                      Q2. Langue parlée dans le ménage
14                                     Q46f. Réduction de la criminalité
15                      Q46g. Amélioration des services de santé de base
16                           Q46h. Satisfaction des besoins en éducation
17                Q46i. Fourniture de services d'eau et d'assainissement
18                                 Q57a. Est tombé malade de la COVID-19
19                          Q57b. Perte de revenu à cause de la COVID-19
20                             Q58a. A reçu le vaccin contre la COVID-19
21 Q58c. Raison principale pour laquelle il est peu probable de vacciner
22                                              Q90d. Possède ordinateur
23                                      Q90f. Possède téléphone portable
24                               Q90g. Téléphone a un accès à l’Internet
25                           Q91c. Emplacement de la toilette ou latrine
26                           Q92a. Maison raccordée au réseau électrique
27                                Q94. Niveau d'instruction du répondant
28                                                  Durée de l'entretien
29                                              Q101.  Sexe du répondant
30                                              Q102.  Race du répondant
31                                Q103. Langue principale de l'entretien

1.3 Choix de variables à analyser

On sélectionne dans le tableau une variable Y que l’on veut expliquer et des variables X1, X2 …X3 qui peuvent servir à expliquer Y. On décide par exemple d’examiner les variables suivantes :

  • vac : A été vacciné contre le covid (Q58A)
  • sex : Sexe (Q101)
  • age : Age (Q1)
  • mil : Milieu Urbain ou rural (URBRUR)
  • reg : région de résidence (REGION)
sel<-don[,c("Q58A","Q101","Q1","URBRUR","REGION")]
colnames(sel)<-c("vac","sex","age","mil","reg")
head(sel)
  vac   sex age    mil          reg
1 Non Femme  27 Urbain YAMOUSSOUKRO
2 Non Femme  52 Urbain      ABIDJAN
3 Oui Homme  21 Urbain      ABIDJAN
4 Oui Femme  45  Rural     MARAHOUE
5 Oui Homme  76  Rural     TCHOLOGO
6 Oui Homme  66 Urbain      ABIDJAN

1.3 Elimination des valeurs manquantes

On ne garde que les lignes du tableau qui sont complètes car autrement il risque d’y avoir des problèmes dans les analyses.

sel <-sel[complete.cases(sel), ]

1.4 Création de nouvelles variables

Effet métropole

On veut créer une variable abi pour les personnes qui résident à Abidjan

sel$abi <- sel$reg=="ABIDJAN"

Classes d’âge

On veut découper la variable âge en trois classes :

sel$age3 <-cut(sel$age, breaks=c(17, 29, 49, 100))
levels(sel$age3) <-c("- de 30 ans","30-49 ans", "50 ans et +")

1.5 Resumé du tableau

Proposez un résumé rapide du tableau

summary(sel)
  vac         sex           age            mil                  reg     
 Non:768   Femme:602   Min.   :18.00   Rural :544   ABIDJAN       :312  
 Oui:432   Homme:598   1st Qu.:24.00   Urbain:656   GBEKE         : 64  
                       Median :32.00                TONKPI        : 64  
                       Mean   :34.84                HAUT-SASSANDRA: 56  
                       3rd Qu.:42.00                PORO          : 48  
                       Max.   :85.00                GÔH           : 40  
                                                    (Other)       :616  
    abi                   age3    
 Mode :logical   - de 30 ans:482  
 FALSE:888       30-49 ans  :542  
 TRUE :312       50 ans et +:176  
                                  
                                  
                                  
                                  

2. ANALYSE UNIVARIEE

Quelles sont les étapes d’analyse d’une variable qualitative de type factor ? On va proposer ci-dessous un programme type

2.1 : Analyse de la variable à expliquer (dépendante) Y

On suppose que la variable à expliquer est le fait d’être vacciné

Fréquence simple

En l’absence de pondération il suffit de calculer les fréquences avec l’instruction table()puis de les afficher en ajoutant le total avec addmargins()

mytab1 <-table(sel$vac)
mytab1

Non Oui 
768 432 
  • Commentaire : 768 personnes déclarent avoir été vaccinées contre 432 qui déclarent ne pas l’avoir été

Pourcentage

On veut ensuite facilement calculer les valeurs en pourcentage en utlisant la fonction prop.table() de R-base

100*prop.table(mytab1)

Non Oui 
 64  36 
  • Commentaire : Les personnes vaccinées représentent 64% des réponses, les non vaccinés 36%

Diagramme en bâton

on veut visualiser la table avec barplot() :

barplot(mytab1)

Améliorer le graphique avec des titres et des couleurs

barplot(mytab1, 
        main = "Y : Vaccination contre le Covid en Côte d'Ivoire",
        sub = "Source : Afrobarometer 2023",
        col = c("red","blue"))

Camembert

On peut également faire un camenbert si on préfère avec pie()

pie(mytab1, 
        main = "Vaccination contre le Covid en Côte d'Ivoire",
        sub = "Source : Afrobarometer 2023",
        col = c("red","blue"))

2.2 Analyse de la variable explicative (indépendante) X

On suppose que la variable explicative (indépendante) est age3 (âge en trois classes)

Fréquence simple

Calculer les fréquences de chaque classe

mytab2 <-table(sel$age3)
mytab2

- de 30 ans   30-49 ans 50 ans et + 
        482         542         176 
  • Commentaire : On trouve 482 personnes de 20 ans et moins, 542 personnes de 30-49 ans et 176 personnes de 50 ans et plus.

Pourcentage

On peut ensuite facilement calculer les valeurs en pourcentage en utlisant la fonction prop.table() de R-base

100*prop.table(mytab2)

- de 30 ans   30-49 ans 50 ans et + 
   40.16667    45.16667    14.66667 
  • Commentaire : Notre échantillon comporte 40% de jeunes, 45% d’adultes et 15% de vieux.

Diagramme en bâton

Visualiser la table avec barplot :

barplot(mytab2)

Améliorer le graphique en ajoutant des titres et des couleurs adaptées :

barplot(mytab2, 
        main = " X : Âge des personnes enquêtées ",
        sub = "Source : Afrobarometer 2023",
        col = c("yellow","orange","brown"))

3. ANALYSE BIVARIEE

Objectif

On veut tester l’existence d’une relation entre les deux variables précédentes. Vous devez formuler deux hypothèses alternatives :

H0 : Il n’y a pas de relation entre X et Y H1 : Il y a une relation entre X et Y

3.1 Création du tableau de contingence

Tableau brut

Créer un tableau de contingence en indiquant en premier la variable indépendante (X) et en second la variable à expliquer (Y)

tabcont<-table(sel$age3,sel$vac)
tabcont
             
              Non Oui
  - de 30 ans 337 145
  30-49 ans   338 204
  50 ans et +  93  83

Ajout des marges

Ajouter à votre tableau les sommes des lignes et des colonnes :

tabtot <- addmargins(tabcont)
tabtot
             
               Non  Oui  Sum
  - de 30 ans  337  145  482
  30-49 ans    338  204  542
  50 ans et +   93   83  176
  Sum          768  432 1200

Pourcentage en ligne

Calculez les pourcentages en lignes pour voir si la fréquence des modalités de Y varie en fonction de celles de X

tabpct <- 100*prop.table(tabcont,1) # Calcule le pourcentage en ligne (1)
round(tabpct,1)                     # Arrondi à un chiffre après la virgule
             
               Non  Oui
  - de 30 ans 69.9 30.1
  30-49 ans   62.4 37.6
  50 ans et + 52.8 47.2
  • Commentaire : Il semble en effet y avoir une relation entre les deux variables. Le taux de personnes vaccinés est plus faible chez les jeunes (30.1%) que chez les adultes (37.6%) ou les vieux (47.2%)

3.2 Visualisation de la relation

Construire un graphique en mosaïque avec mosaicplot()

mosaicplot(tabcont)

Améliorer le graphique avec des titres et des couleurs :

mosaicplot(tabcont, 
           main= "Vaccination et âge en Côte d'Ivoire en 2021",
           sub = "Source : Afrobarometer",
           xlab = "Classes d'âge",
           ylab = "Vaccination Covid",
           col = c("red","blue"))

3.3 Test du chi-2

On va tester si les différences de pourcentage sont significatives ou sont l’effet du hasard.

Hypothèse nulle

Rappelez l’hypothèse H0 :

H0 : il n’y a pas de relation entre X et Y. Les variations en Y en fonction de X sont l’effet du hasard.

Test

Réalisez un test du chi-2 à l’aide de la fonction chisq.test() et commentez les résultats du test.

chisq.test(tabcont)

    Pearson's Chi-squared test

data:  tabcont
X-squared = 17.468, df = 2, p-value = 0.000161
  • Commentaire : Notre tableau comportait 3 lignes et 2 colonnes et avait donc 2 degrés de liberté. Le chi-2 du tableau est de 17.48 ce qui donne une p-value de 0.000161. Il y a donc moins d’une chance sur 1000 (p < 0.001) que les différences soient l’effet du hasard et que H0 soit vraie.

Conclusion

Au vu des résultats on rejette H0 et on accepte H1. On conclue avec un risque d’erreur très faible (p < 0.001) qu’il existe une relation entre l’âge et le fait d’être vacciné en Côte d’Ivoire en 2021.

4. A VOUS DE JOUER…

Testez rapidement trois autres relations possibles

4.1 Vaccination et sexe

# tableau de contingence
tabcont <- table(sel$sex,sel$vac)
# Pourcentages
prop.table(tabcont,1)
       
              Non       Oui
  Femme 0.6744186 0.3255814
  Homme 0.6053512 0.3946488
# graphique
plot(tabcont)

# test
chisq.test(tabcont)

    Pearson's Chi-squared test with Yates' continuity correction

data:  tabcont
X-squared = 5.9151, df = 1, p-value = 0.01501
  • Conclusion : Les femmes sont dans l’ensemble moins vaccinées (32.5%) que les hommes (39.5%). On peut affirmer avec un risque d’erreur inférieur à 0.05 que cette relation est significative.

4.2 Vaccination et milieu urbain-rural

# tableau de contingence
tabcont <- table(sel$sex,sel$mil)
# Pourcentages
prop.table(tabcont,1)
       
            Rural    Urbain
  Femme 0.4551495 0.5448505
  Homme 0.4515050 0.5484950
# graphique
plot(tabcont)

# test
chisq.test(tabcont)

    Pearson's Chi-squared test with Yates' continuity correction

data:  tabcont
X-squared = 0.0047352, df = 1, p-value = 0.9451
  • Conclusion : Il n’y a pas de différence significative de vaccination entre les personnes résidant en milieu urbain et rural.

4.3 Vaccination et Abidjan

# tableau de contingence
tabcont <- table(sel$sex,sel$abi)
# Pourcentages
prop.table(tabcont,1)
       
            FALSE      TRUE
  Femme 0.7408638 0.2591362
  Homme 0.7391304 0.2608696
# graphique
plot(tabcont)

# test
chisq.test(tabcont)

    Pearson's Chi-squared test with Yates' continuity correction

data:  tabcont
X-squared = 6.9301e-06, df = 1, p-value = 0.9979
  • Conclusion : Il n’y a pas de différence significative de vaccination entre les personnes résidant à Abidjan et dans le reste du pays.